/*******************************************************************************
 *                                    ZLG
 *                         ----------------------------
 *                         innovating embedded platform
 *
 * Copyright (c) 2001-present Guangzhou ZHIYUAN Electronics Co., Ltd.
 * All rights reserved.
 *
 * Contact information:
 * web site:    https://www.zlg.cn
 *******************************************************************************/
#ifndef __HPM_INTERRUPT_H
#define __HPM_INTERRUPT_H

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus*/
#include "common/hpm_common.h"
#include "riscv/riscv_core.h"
#include "core/include/hpm6e00_regs_base.h"
#include "core/include/hpm6e00_regs_csr.h"
#include "core/include/hpm6e00_plic.h"
#include <stdint.h>


/**
 * \brief 使能掩码全局中断
 */
__attribute__((always_inline)) static inline void enable_global_irq(uint32_t mask){
    set_csr(CSR_MSTATUS, mask);
}


/**
 * \brief 关闭掩码全局中断和返回 mstatus 寄存器值
 */
__attribute__((always_inline)) static inline uint32_t disable_global_irq(uint32_t mask){
    return read_clear_csr(CSR_MSTATUS, mask);
}

/**
 * \brief 从中断控制器使能中断
 */
__attribute__((always_inline)) static inline void enable_irq_from_intc(void){
    set_csr(CSR_MIE, CSR_MIE_MEIE_MASK);
}

/**
 * \brief 从中断控制器关闭中断
 */
__attribute__((always_inline)) static inline void disable_irq_from_intc(void){
    clear_csr(CSR_MIE, CSR_MIE_MEIE_MASK);
}

/* \brief 机器模式设置中断阈值 */
#define intc_m_set_threshold(threshold)  intc_set_threshold(HPM_PLIC_TARGET_M_MODE, threshold)

/* \brief 机器模式完成中断 */
#define intc_m_complete_irq(irq) intc_complete_irq(HPM_PLIC_TARGET_M_MODE, irq)


/**
 * \brief 设置中断阈值
 *
 * \param[in] target    目标模式
 * \param[in] threshold 中断阈值
 */
__attribute__((always_inline)) static inline void intc_set_threshold(uint32_t target, uint32_t threshold){
    __plic_set_threshold(HPM_PLIC_BASE, target, threshold);
}

/**
 * \brief 完成中断
 *
 * \param[in] target 目标模式
 * \param[in] irq    要完成的中断号
 */
__attribute__((always_inline)) static inline void intc_complete_irq(uint32_t target, uint32_t irq){
    __plic_complete_irq(HPM_PLIC_BASE, target, irq);
}


#ifdef __cplusplus
}
#endif  /* __cplusplus  */

#endif


